package com.example.canteen;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.util.Base64;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

import com.example.canteen.javaBean.JsonRootBean;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.tencent.wxpayface.IWxPayfaceCallback;
import com.tencent.wxpayface.WxPayFace;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Stack;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class MainActivity extends Activity {
    private final String[] ANS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
    private final int[] KEY_CODE = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54};
    private final String AVM = "99219000";
    private final String MY_APPID_1 = BuildConfig.MY_APPID_1;
    private final String KEY_1 = BuildConfig.KEY_1;
    private final String MY_APPID = BuildConfig.MY_APPID;
    private final String KEY = BuildConfig.KEY;
    private final String URL = BuildConfig.API_URL_HOST;
    private final ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    private final StringBuffer sb = new StringBuffer();
    private final StringBuffer buffer = new StringBuffer();
    private final Map<Integer, Integer> soundMap = new HashMap<>();
    private boolean flag = false; //文本是否符合规范
    private boolean flag_2 = false; //是否按了回车键
    private boolean flag_3 = true; //键盘监听标志
    private boolean flag_4 = false; //获取的bean是否正确
    private String rawData;
    private Data data;
    private Bean bean;
    private TextView tv;
    private TextView time;
    private Button submit;
    private View line;
    private repeatBtn repeatBtn;
    private String CARD_ID = "";
    private LoadProgressDialog loadProgressDialog;
    private pay_msg_ProgressDialog pay_msg_progressDialog;
    private pay_fail_ProgressDialog pay_fail_progressDialog;
    private String fee = "0.00";
    private long start_time;
    private long end_time;
    private SoundPool soundpool;


    @SuppressLint({"WrongConstant", "ShowToast"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        initView();
        //初始化刷脸
        initFacePay();
        //初始化音效池
        initSoundPool();
        //显示时间
        new TimeThread().start();
        //按钮呼吸动画
        repeatBtn = new repeatBtn(submit);
        repeatBtn.showRepeatBtn();
        submit.setFocusable(false);
        submit.setOnClickListener(v -> {
            Log.d("TAG", "点击了按钮");
            submit.setFocusable(false);
            if (flag_2) {
                if (flag) {
                    loadProgressDialog.show();
                    end_time = System.currentTimeMillis();
                    if (flag_4 && rawData != null && end_time - start_time <= 60 * 60 * 1000) {
                        setTvEmpty();
                        getWxpayfaceUserInfo();
                    } else {
                        rawData();
                    }
                    flag_2 = false;
                } else {
                    mediaPlayer(12);
                    Toast.makeText(getBaseContext(), "您输入的金额有误", 1000).show();
                }
            } else {
                mediaPlayer(12);
                Toast.makeText(getBaseContext(), "请确认输入金额无误后，按确认键", 1000).show();
            }
            repeatBtn.showRepeatBtn();
        });

        tv.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^(([1-9]\\d*)|([0]))(\\.(\\d){0,2})?$");
                java.util.regex.Matcher match = pattern.matcher(tv.getText().toString());
                String string = tv.getText().toString();
                double v;
                try {
                    v = Double.parseDouble(string);
                } catch (NumberFormatException e) {
                    v = 0;
                }
                if (!match.matches() || v > 99.99) {
                    tv.setTextColor(Color.parseColor("#FF0000"));
                    flag = false;
                    Log.d("flag", "false");
                } else {
                    tv.setTextColor(Color.parseColor("#FFFFFF"));
                    flag = true;
                    Log.d("flag", "true");
                }
                int width = tv.getWidth();
                Log.d("TestView Width", String.valueOf(width));
                ViewGroup.LayoutParams params = line.getLayoutParams();
                if (flag_2) {
                    params.width = width + 150;
                } else {
                    params.width = width + 50;
                }
                line.setLayoutParams(params);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });


    }


    @SuppressLint("SetTextI18n")
    private void initView() {
        ActionBar actionBar = getActionBar();
        actionBar.hide();
        tv = findViewById(R.id.tv);
        time = findViewById(R.id.time);
        TextView id = findViewById(R.id.id);
        submit = findViewById(R.id.submit);
        line = findViewById(R.id.line);

        id.setText("机器编号：" + AVM);
        loadProgressDialog = new LoadProgressDialog(MainActivity.this, "请稍等……");
    }

    private void initSoundPool() {
        loadProgressDialog.show();
        //当前系统的SDK版本大于等于21(Android 5.0)时
        SoundPool.Builder builder = new SoundPool.Builder();
        //传入音频数量
        builder.setMaxStreams(16);
        //AudioAttributes是一个封装音频各种属性的方法
        AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
        //设置音频流的合适的属性
        attrBuilder.setLegacyStreamType(AudioManager.STREAM_ALARM);//STREAM_MUSIC
        //加载一个AudioAttributes
        builder.setAudioAttributes(attrBuilder.build());
        soundpool = builder.build();
        soundMap.put(0, soundpool.load(this, R.raw.a0, 1));
        soundMap.put(1, soundpool.load(this, R.raw.a1, 1));
        soundMap.put(2, soundpool.load(this, R.raw.a2, 1));
        soundMap.put(3, soundpool.load(this, R.raw.a3, 1));
        soundMap.put(4, soundpool.load(this, R.raw.a4, 1));
        soundMap.put(5, soundpool.load(this, R.raw.a5, 1));
        soundMap.put(6, soundpool.load(this, R.raw.a6, 1));
        soundMap.put(7, soundpool.load(this, R.raw.a7, 1));
        soundMap.put(8, soundpool.load(this, R.raw.a8, 1));
        soundMap.put(9, soundpool.load(this, R.raw.a9, 1));
        soundMap.put(10, soundpool.load(this, R.raw.dian, 1));
        soundMap.put(11, soundpool.load(this, R.raw.pay_type, 1));
        soundMap.put(12, soundpool.load(this, R.raw.cuowu, 1));
        soundMap.put(13, soundpool.load(this, R.raw.a10, 1));
        soundMap.put(14, soundpool.load(this, R.raw.shoudao, 1));
        soundMap.put(15, soundpool.load(this, R.raw.yuan, 1));

        soundpool.setOnLoadCompleteListener((soundPool, sampleId, status) -> {
            if (sampleId == 15) {
                loadProgressDialog.dismiss();
            }
        });
    }

    private void showSuccessDialog(String msg) {
        runOnUiThread(() -> {
            pay_msg_progressDialog = new pay_msg_ProgressDialog(MainActivity.this);
            pay_msg_progressDialog.setMessage(msg);
            pay_msg_progressDialog.show();
            pay_msg_progressDialog.setOnKeyDownListener(MainActivity.this::onKeyDown);
        });


    }

    private void showFailDialog(String msg) {
        runOnUiThread(() -> {
            pay_fail_progressDialog = new pay_fail_ProgressDialog(MainActivity.this);
            pay_fail_progressDialog.setMessage(msg);
            pay_fail_progressDialog.show();
            pay_fail_progressDialog.setOnKeyDownListener(MainActivity.this::onKeyDown);
        });

    }

    private void DialogDismiss() {
        if (pay_fail_progressDialog != null && pay_fail_progressDialog.isShowing()) {
            pay_fail_progressDialog.dismiss();
        }
        if (pay_msg_progressDialog != null && pay_msg_progressDialog.isShowing()) {
            pay_msg_progressDialog.dismiss();
        }
        if (loadProgressDialog.isShowing()) {
            loadProgressDialog.dismiss();
        }
    }

    private class TimeThread extends Thread {
        @Override
        public void run() {
            do {
                try {
                    Thread.sleep(1000);
                    Message msg = new Message();
                    msg.what = 1;
                    mHandler.sendMessage(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } while (true);
        }
    }


    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                long sysTime = System.currentTimeMillis();//获取系统时间
                CharSequence sysTimeStr = DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime);//时间显示格式
                time.setText(sysTimeStr); //更新时间
            }
        }
    };

    private void checkFeeAndPlayer(String actualmoney) {
        cachedThreadPool.execute(() -> {
            String[] type = actualmoney.split("");
            Log.d("actualmoney.length()", String.valueOf(actualmoney.length()));
            Log.d("type", Arrays.toString(type));
            switch (actualmoney.length()) {
                case 1:
                    String[] s1 = new String[]{"0", ".", "0", actualmoney};
                    Log.d("TAG", Arrays.toString(s1));
                    promptPlayer(s1);
                    break;
                case 2:
                    String[] s2;
                    if (actualmoney.charAt(1) == '0') {
                        s2 = new String[]{"0", ".", actualmoney.substring(0, 1)};
                    } else {
                        s2 = new String[]{"0", ".", actualmoney.substring(0, 1), actualmoney.substring(1, 2)};
                    }
                    Log.d("TAG", Arrays.toString(s2));
                    promptPlayer(s2);
                    break;
                case 3:
                    String[] s3;
                    if (type[3].equals("0")) {
                        if (type[2].equals("0")) {
                            s3 = new String[]{type[1]};
                        } else {
                            s3 = new String[]{type[1], ".", type[2]};
                        }
                    } else {
                        s3 = new String[]{type[1], ".", type[2], type[3]};
                    }
                    Log.d("TAG", Arrays.toString(s3));
                    promptPlayer(s3);
                    break;
                case 4:
                    String[] s4;
                    if (type[4].equals("0")) {
                        if (type[3].equals("0")) {
                            s4 = numberFormat(type[1], type[2]);
                        } else {
                            String[] strings = numberFormat(type[1], type[2]);
                            if (strings.length == 1) {
                                s4 = new String[]{strings[0], ".", type[3]};
                            } else if (strings.length == 2) {
                                s4 = new String[]{strings[0], strings[1], ".", type[3]};
                            } else {
                                s4 = new String[]{strings[0], strings[1], strings[2], ".", type[3]};
                            }

                        }
                    } else {
                        String[] strings = numberFormat(type[1], type[2]);
                        if (strings.length == 1) {
                            s4 = new String[]{strings[0], ".", type[3], type[4]};
                        } else if (strings.length == 2) {
                            s4 = new String[]{strings[0], strings[1], ".", type[3], type[4]};
                        } else {
                            s4 = new String[]{strings[0], strings[1], strings[2], ".", type[3], type[4]};
                        }
                    }
                    Log.d("TAG", Arrays.toString(s4));
                    promptPlayer(s4);
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + actualmoney.length());
            }
        });

    }

    private String[] numberFormat(String num1, String num2) {
        String[] s;
        if (Integer.parseInt(num1 + num2) % 10 == 0) {
            if (num1.equals("1")) {
                s = new String[]{"10"};
            } else {
                s = new String[]{num1, "10"};
            }
        } else if (num1.equals("1")) {
            s = new String[]{"10", num2};
        } else {
            s = new String[]{num1, "10", num2};
        }
        return s;
    }

    private void promptPlayer(String[] type) {
        Stack<String> stack1 = new Stack<>();
        Stack<String> stack = new Stack<>();
        for (String s : type) {
            stack1.push(s);
            Log.d("stack1", s);
        }
        Log.d("stack1", String.valueOf(stack1.size()));
        for (int i = 0; i < type.length; i++) {
            String pop = stack1.pop();
            stack.push(pop);
            Log.d("stack", pop);
        }
        mediaPlayer(14);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        promptPlayer2(stack, stack.size());
    }

    private void promptPlayer2(Stack<String> stack, int size) {
        size--;
        mediaPlayer(getMusicId(stack.pop()));
        Log.d("promptPlayer2", String.valueOf(stack.size()));
        int finalSize = size;
        try {
            Thread.sleep(220);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (finalSize != 0) {
            promptPlayer2(stack, stack.size());
        } else {
            mediaPlayer(15);
        }
    }

    private int getMusicId(String type) {
        int r;
        switch (type) {
            case "shoudao":
                r = 14;
                break;
            case "yuan":
                r = 15;
                break;
            case "10":
                r = 13;
                break;
            case ".":
                r = 10;
                break;
            default:
                r = Integer.parseInt(type);
                break;
        }
        return r;
    }

    //按键提示音
    private void mediaPlayer(int index) {
        soundpool.play(soundMap.get(index), 1, 1, 1, 0, 1);
    }


    @SuppressLint("SetTextI18n")
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d("TAG", String.valueOf(keyCode));
        DialogDismiss();
        if (sb.length() >= 5 && keyCode == 67) {
            sb.delete(sb.length() - 1, sb.length());
            tv.setText(sb);
            return true;
        } else if (sb.length() >= 5 && keyCode == 160) {

        } else if (sb.length() >= 5) {
            return true;
        }

        if (flag_2) {
            if (keyCode == 67) {
                setTvEmpty();
                flag_2 = false;
                return true;
            }
            if (keyCode != 74 && keyCode != 66) {
                flag_2 = false;
            }
        }
        buffer.append(keyCode);
        if (flag_3) {
            switch (keyCode) {
                case 74:
                    if (flag_2) {
                        flag_3 = false;
                        Log.d("TAG", String.valueOf(false));
                    }
                    break;
                case 158:
                    tv.setText(sb.append("."));
                    mediaPlayer(10);
                    return true;
                case 144:
                    tv.setText(sb.append("0"));
                    mediaPlayer(0);
                    return true;
                case 145:
                    tv.setText(sb.append("1"));
                    mediaPlayer(1);
                    return true;
                case 146:
                    tv.setText(sb.append("2"));
                    mediaPlayer(2);
                    return true;
                case 147:
                    tv.setText(sb.append("3"));
                    mediaPlayer(3);
                    return true;
                case 148:
                    tv.setText(sb.append("4"));
                    mediaPlayer(4);
                    return true;
                case 149:
                    tv.setText(sb.append("5"));
                    mediaPlayer(5);
                    return true;
                case 150:
                    tv.setText(sb.append("6"));
                    mediaPlayer(6);
                    return true;
                case 151:
                    tv.setText(sb.append("7"));
                    mediaPlayer(7);
                    return true;
                case 152:
                    tv.setText(sb.append("8"));
                    mediaPlayer(8);
                    return true;
                case 153:
                    tv.setText(sb.append("9"));
                    mediaPlayer(9);
                    return true;
                case 160:
                    Log.d("Enter", "回车");
                    if (sb.toString().equals("0") || sb.toString().equals("0.") || sb.toString().equals("0.0") || sb.toString().equals("0.00")) {
                        mediaPlayer(12);
                        sb.delete(0, sb.length());
                        setTvEmpty();
                        return true;
                    }
                    if (flag && buffer.indexOf("74") == -1) {
                        Log.d("SB", sb.toString());
                        if (!sb.toString().contains(".") && sb.length() != 0) {
                            fee = sb + "00";
                            tv.setText(sb + ".00");
                        } else if (sb.toString().indexOf(".") == sb.length() - 1 && sb.length() != 0) {
                            fee = sb.substring(0, sb.length() - 1) + "00";
                            tv.setText(sb + "00");
                        } else if (sb.toString().indexOf(".") == sb.length() - 2 & sb.length() != 0) {
                            String[] split = sb.toString().split("\\.");
                            if (split[0].equals("0")) {
                                fee = split[1] + "0";
                            } else {
                                fee = split[0] + split[1] + "0";
                            }
                            tv.setText(sb + "0");
                        } else if (sb.length() != 0) {
                            String[] split = sb.toString().split("\\.");
                            if (split[0].equals("0")) {
                                if (split[1].charAt(0) == '0') {
                                    fee = split[1].substring(1, 2);
                                } else {
                                    fee = split[1];
                                }
                            } else {
                                fee = split[0] + split[1];
                            }
                        }
                        Log.d("FEE", fee);
                        sb.delete(0, sb.length());
                        flag_2 = true;
                        mediaPlayer(11);
                    }
                    Log.d("buffer", "==" + buffer.toString());
                    buffer.delete(0, buffer.length());
                    break;
                case 67:
                    if (sb.length() > 0) {
                        sb.delete(sb.length() - 1, sb.length());
                        tv.setText(sb);
                    }
                    return true;
            }
        } else {
            String keyCode1;
            if (keyCode != 66) {
                keyCode1 = ANS[Arrays.binarySearch(KEY_CODE, keyCode)];
                CARD_ID += keyCode1;
            } else {
                StringBuilder s = new StringBuilder();
                for (int i = CARD_ID.length() - 2; i >= 0; i -= 2) {
                    s.append(CARD_ID.substring(i, i + 2));
                }
                String cardId = s.toString();
                Log.d("card=", s.toString());
                CARD_ID = "";
                buffer.delete(0, buffer.length());
                flag_2 = false;
                flag_3 = true;
                cachedThreadPool.execute(() -> {
                    runOnUiThread(() -> loadProgressDialog.show());
//                        payForCard(cardId);
                    payForICcard(cardId);
                });
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private void initFacePay() {
        Map<String, String> m1 = new HashMap<>();
//      m1.put("ip", "192.168.1.1"); //若没有代理,则不需要此行
//      m1.put("port", "8888");//若没有代理,则不需要此行
//      m1.put("user", mEtnUser.getText().toString());//若没有代理,则不需要此行
//      m1.put("passwd", mEtnPassword.getText().toString());//若没有代理,则不需要此行
//      m1.put("proxy_type", 1 ); //若没有代理,则不需要此行
//      m1.put("perform_mode", "LOW_PERFORM");//低性能表现，默认关闭美颜等

        WxPayFace.getInstance().initWxpayface(this, m1, new IWxPayfaceCallback() {
            @Override
            public void response(Map info) {

                if (info == null) {
                    Log.d("initFacePay", "调用返回为空, 请查看日志");
                    new RuntimeException("调用返回为空").printStackTrace();
                    return;
                }
                String code = (String) info.get("return_code");
                String msg = (String) info.get("return_msg");

                Log.d("TAG", "初始化完成" + code + "   " + msg);

            }
        });
    }

    private void rawData() {
        WxPayFace.getInstance().getWxpayfaceRawdata(new IWxPayfaceCallback() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void response(final Map info) {
                if (info == null) {

                    Log.d("rawData", "调用返回为空, 请查看日志");
                    new RuntimeException("调用返回为空").printStackTrace();
                    return;
                }
                String code = (String) info.get("return_code");
                String msg = (String) info.get("return_msg");
                rawData = (String) info.get("rawdata");
                start_time = System.currentTimeMillis();
                Log.d("TAG", "初始化完成" + code + "   " + msg + "  " + rawData);
                cachedThreadPool.execute(() -> post());
            }
        });
    }

    private String getSign(boolean flag, String str) {
        if (flag) {
            str = Base64.encodeToString(str.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP);
        }
        String signMd5 = md5(str).toLowerCase();
        String sign1 = signMd5.substring(1, 2) + signMd5.substring(3, 4) + signMd5.substring(5, 6) + signMd5.substring(7) + signMd5.substring(0, 1) + signMd5.substring(2, 3) + signMd5.substring(4, 5) + signMd5.substring(6, 7);
        String sign = md5(sign1).toLowerCase();
        Log.d("getSign", sign);
        return sign;

    }

    private void post() {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(BuildConfig.API_AUTHINFO_URL_HOST);
        try {
            String decode = URLEncoder.encode(rawData);
            @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date(System.currentTimeMillis());
            String datetime = simpleDateFormat.format(date);
            String str = "avm=" + AVM + "&datetime=" + datetime + "&key=" + KEY_1 + "&myappid=" + MY_APPID_1 + "&rawdata=" + decode;
            String sign = getSign(false, str);
            // 为httpPost设置HttpEntity对象
            Log.d("md5：", sign);
            List<NameValuePair> parameters = new ArrayList<>();
            parameters.add(new BasicNameValuePair("sign", sign));
            parameters.add(new BasicNameValuePair("avm", AVM));
            parameters.add(new BasicNameValuePair("datetime", datetime));
            parameters.add(new BasicNameValuePair("myappid", MY_APPID_1));
            parameters.add(new BasicNameValuePair("rawdata", decode));
            HttpEntity entity = new UrlEncodedFormEntity(parameters);
            httpPost.setEntity(entity);
            // httpClient执行httpPost表单提交
            HttpResponse response = httpClient.execute(httpPost);
            // 得到服务器响应实体对象
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity, "utf-8");
                Log.d("response post", string);
                Gson gson = new Gson();
                bean = gson.fromJson(string, Bean.class);
                data = bean.getData();
                if (bean.getFlag() == 0) {
                    flag_4 = true;
                    getWxpayfaceUserInfo();
                } else {
                    flag_4 = false;
                    Log.d("Error", "flag值错误");
                    DialogDismiss();
                    setTvEmpty();
                    showFailDialog("服务器异常，请稍后再试！");
                }
            } else {
                Log.d("fail", "服务器无响应！");
                showFailDialog("服务器无响应，请稍后再试！");
                DialogDismiss();
                setTvEmpty();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            httpClient.getConnectionManager().shutdown();
        }
    }

    private void getWxpayfaceUserInfo() {
        Log.d("TAG", "getWxpayfaceUserInfo");
        Map<String, String> m1 = new HashMap<>();
        m1.put("appid", data.getAppid()); // 公众号，必填
        m1.put("mch_id", data.getMch_id()); // 商户号，必填
//        m1.put("sub_appid", "xxxxxxxxxxxxxx"); // 子商户公众账号ID(非服务商模式不填)
//        m1.put("sub_mch_id", "填您的子商户号"); // 子商户号(非服务商模式不填)
        m1.put("store_id", bean.getAvm()); // 门店编号，必填
        m1.put("face_authtype", "FACEID-ONCE"); // 人脸识别模式， FACEID-ONCE`: 人脸识别(单次模式) FACEID-LOOP`: 人脸识别(循环模式), 必填
        m1.put("authinfo", data.getAuthinfo()); // 调用凭证，详见上方的接口参数
//        m1.put("ask_unionid", "1"); // 是否获取union_id    0：获取    1：不获取
        Log.d("appid", data.getAppid()); // 公众号，必填
        Log.d("mch_id", data.getMch_id()); // 商户号，必填
//        m1.put("sub_appid", "xxxxxxxxxxxxxx"); // 子商户公众账号ID(非服务商模式不填)
//        m1.put("sub_mch_id", "填您的子商户号"); // 子商户号(非服务商模式不填)
        Log.d("store_id", bean.getAvm()); // 门店编号，必填
        Log.d("face_authtype", "FACEID-ONCE"); // 人脸识别模式， FACEID-ONCE`: 人脸识别(单次模式) FACEID-LOOP`: 人脸识别(循环模式), 必填
        Log.d("authinfo", data.getAuthinfo()); // 调用凭证，详见上方的接口参数

        WxPayFace.getInstance().getWxpayfaceUserInfo(m1, new IWxPayfaceCallback() {
            @Override
            public void response(Map info) {
                Log.d("SUCCESS", info.toString());
                if (info == null) {
                    new RuntimeException("调用返回为空").printStackTrace();
                    Log.d("TAG", "调用返回为空");
                    return;
                }
                Log.d("TAG", "getinfo");
                String code = (String) info.get("return_code"); // 错误码
                Integer errcode = (Integer) info.get("err_code"); // 二级错误码
                String msg = (String) info.get("return_msg"); // 错误码描述
                String openid = Objects.requireNonNull(info.get("openid")).toString(); // openid
                String sub_openid = "";
                if (info.get("sub_openid") != null)
                    sub_openid = info.get("sub_openid").toString(); // 子商户号下的openid(服务商模式)
                String nickName = info.get("nickname").toString(); // 微信昵称
                String token = "";
                if (info.get("token") != null)
                    token = info.get("token").toString(); // facesid,用户获取unionid
                if (code == null || openid == null || nickName == null || !code.equals("SUCCESS")) {
                    new RuntimeException("调用返回非成功信息,return_msg:" + msg + "   ").printStackTrace();

                    if (loadProgressDialog.isShowing()) {
                        loadProgressDialog.dismiss();
                    }
                    setTvEmpty();
                    showFailDialog("调用返回非成功信息,请稍后重试");
                    return;
                }
                Log.d("code", code);
                Log.d("errcode", String.valueOf(errcode));
                Log.d("msg", msg);
                Log.d("openid", openid);
                Log.d("sub_openid", sub_openid);
                Log.d("nickName", nickName);
                Log.d("token", token);

                cachedThreadPool.execute(() -> payForFace(openid));
            }
        });

    }

    private void payForOpenid(String openid) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost("http://test.easytouch-manager.com:7008/Interface/trade/smilepayFtoken.do");
        try {
            @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            Date date = new Date(System.currentTimeMillis());
            String datetime = simpleDateFormat.format(date);
            String pay_type = "75";   //73刷卡75刷脸
            String out_trade_no = AVM + "-" + datetime + "-" + pay_type;
            String subject = "餐厅";
            String total_price = fee;

            String goods_detail = "{\"rows\":[{\"box\":\"09\",\"aisle\":\"911\",\"aisleNo\":\"01\",\"barcode\":\"000000\",\"name\":\"餐厅\",\"price\":\"" + total_price + "\",\"price_act\":\"" + total_price + "\"}]}";
            Log.d("goods_detail", goods_detail);
            String str = "avm=" + AVM + "&datetime=" + datetime.substring(0, 14) + "&ftoken=" + openid + "&goods_detail=" + goods_detail + "&key=" + KEY_1 + "&myappid=" + MY_APPID_1 + "&subject=" + subject + "&total_price=" + total_price + "&total_price_act=" + total_price;
            String sign = getSign(true, str);
            // 为httpPost设置HttpEntity对象
            Log.d("str：", str);

            List<NameValuePair> parameters = new ArrayList<>();
            parameters.add(new BasicNameValuePair("sign", sign));
            parameters.add(new BasicNameValuePair("ftoken", openid));
            parameters.add(new BasicNameValuePair("avm", AVM));
            parameters.add(new BasicNameValuePair("datetime", datetime.substring(0, 14)));
            parameters.add(new BasicNameValuePair("pay_type", pay_type));
            parameters.add(new BasicNameValuePair("myappid", MY_APPID_1));
            parameters.add(new BasicNameValuePair("total_price", total_price));
            parameters.add(new BasicNameValuePair("total_price_act", total_price));
            parameters.add(new BasicNameValuePair("subject", subject));
            parameters.add(new BasicNameValuePair("out_trade_no", out_trade_no));
            parameters.add(new BasicNameValuePair("goods_detail", goods_detail));
            parameters.add(new BasicNameValuePair("terminal_params", "canting"));
            HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8");

            Log.d("entity====", EntityUtils.toString(entity, "UTF-8"));
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            httpPost.setHeader("Accept", "application/json;charset=utf-8");
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity, "utf-8");
                //数据处理
                responseReader(string);
                Log.d("response", string);
            } else {

                runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器无响应", Toast.LENGTH_SHORT).show());
                Log.d("fail", "服务器无响应！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (loadProgressDialog.isShowing()) {
                loadProgressDialog.dismiss();
            }
            httpClient.getConnectionManager().shutdown();
        }
    }

    private void payForCard(String cardId) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost("http://test.easytouch-manager.com:7008/Interface/trade/smilepayFtoken.do");
        try {
            @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            Date date = new Date(System.currentTimeMillis());
            String datetime = simpleDateFormat.format(date);
            String pay_type = "73";   //73刷卡75刷脸
            String out_trade_no = AVM + "-" + datetime + "-" + pay_type;
            String subject = "餐厅";
            String total_price = fee;
            String goods_detail = "{\"rows\":[{\"box\":\"09\",\"aisle\":\"911\",\"aisleNo\":\"01\",\"barcode\":\"000000\",\"name\":\"餐厅\",\"price\":\"" + total_price + "\",\"price_act\":\"" + total_price + "\"}]}";
            Log.d("goods_detail", goods_detail);
            String str = "avm=" + AVM + "&datetime=" + datetime.substring(0, 14) + "&ftoken=" + cardId + "&goods_detail=" + goods_detail + "&key=" + KEY_1 + "&myappid=" + MY_APPID_1 + "&subject=" + subject + "&total_price=" + total_price + "&total_price_act=" + total_price;
            String sign = getSign(true, str);
            // 为httpPost设置HttpEntity对象
            Log.d("str：", str);

            List<NameValuePair> parameters = new ArrayList<>();
            parameters.add(new BasicNameValuePair("sign", sign));
            parameters.add(new BasicNameValuePair("ftoken", cardId));
            parameters.add(new BasicNameValuePair("avm", AVM));
            parameters.add(new BasicNameValuePair("datetime", datetime.substring(0, 14)));
            parameters.add(new BasicNameValuePair("pay_type", pay_type));
            parameters.add(new BasicNameValuePair("myappid", MY_APPID_1));
            parameters.add(new BasicNameValuePair("total_price", total_price));
            parameters.add(new BasicNameValuePair("total_price_act", total_price));
            parameters.add(new BasicNameValuePair("subject", subject));
            parameters.add(new BasicNameValuePair("out_trade_no", out_trade_no));
            parameters.add(new BasicNameValuePair("goods_detail", goods_detail));
            parameters.add(new BasicNameValuePair("terminal_params", "canting"));
            HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8");
            Log.d("entity====", EntityUtils.toString(entity));
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            httpPost.setHeader("Accept", "application/json;charset=utf-8");
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity, "utf-8");
                responseReader(string);
                Log.d("response", string);
            } else {
                Log.d("fail", "服务器无响应！");
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器无响应", Toast.LENGTH_SHORT).show());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (loadProgressDialog.isShowing()) {
                loadProgressDialog.dismiss();
            }
            httpClient.getConnectionManager().shutdown();
        }
    }

    private void payForICcard(String cardId) {
        HttpClient httpClient = new DefaultHttpClient();
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 3000);
        HttpPost httpPost = new HttpPost(URL);
        try {
            @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date(System.currentTimeMillis());

            String datetime = simpleDateFormat.format(date);
            Log.d("TAG", fee);
            String amount = fee;
            Log.d("amount", amount);
            String comId = "3";
            String str = "amount=" + amount + "&avm=" + AVM + "&comId=" + comId + "&datetime=" + datetime + "&key=" + KEY + "&myappid=" + MY_APPID + "&number=" + cardId;
            String sign = getSign(true, str);
            Log.d("str", str);
            String json = "sign=" + sign + "&amount=" + amount + "&avm=" + AVM + "&comId=" + comId + "&datetime=" + datetime + "&myappid=" + MY_APPID + "&number=" + cardId;

            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            httpPost.setEntity(new StringEntity(json, "UTF-8"));
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity responseEntity = httpResponse.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity, "utf-8");
                readJson(string);
                Log.d("response payForICcard", string);
            } else {
                Log.d("fail", "服务器无响应！");
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器无响应", Toast.LENGTH_SHORT).show());
            }
        } catch (ConnectTimeoutException e) {
            showFailDialog("请求超时，请检查网络状态");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            showFailDialog("转码异常");
        } catch (IOException e) {
            e.printStackTrace();
            showFailDialog("读取异常");
        } catch (JSONException e) {
            showFailDialog("服务器异常");
            e.printStackTrace();
        } finally {
            // 释放资源
            httpClient.getConnectionManager().shutdown();
            DialogDismiss();
            setTvEmpty();
        }
    }

    private void payForFace(String openid) {
        HttpClient httpClient = new DefaultHttpClient();
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 3000);
        HttpPost httpPost = new HttpPost(URL);
        try {
            @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date(System.currentTimeMillis());
            String datetime = simpleDateFormat.format(date);
            Log.d("TAG", fee);
            String amount = fee;
            Log.d("amount", amount);
            String comId = "3";
            String str = "amount=" + amount + "&avm=" + AVM + "&comId=" + comId + "&datetime=" + datetime + "&key=" + KEY + "&myappid=" + MY_APPID + "&openId=" + openid;
            String sign = getSign(true, str);
            Log.d("str", str);
            String json = "sign=" + sign + "&amount=" + amount + "&avm=" + AVM + "&comId=" + comId + "&datetime=" + datetime + "&myappid=" + MY_APPID + "&openId=" + openid;

            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            httpPost.setEntity(new StringEntity(json, "UTF-8"));
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity responseEntity = httpResponse.getEntity();
            if (responseEntity != null) {
                String string = EntityUtils.toString(responseEntity, "utf-8");
                readJson(string);
                Log.d("response payForFace", string);
            } else {
                Log.d("fail", "服务器无响应！");
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "服务器无响应", Toast.LENGTH_SHORT).show());
            }
        } catch (ConnectTimeoutException e) {
            showFailDialog("请求超时，请检查网络状态");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            showFailDialog("转码异常");
        } catch (IOException e) {
            e.printStackTrace();
            showFailDialog("读取异常");
        } catch (JSONException e) {
            showFailDialog("服务器异常");
            e.printStackTrace();
        } finally {
            // 释放资源
            httpClient.getConnectionManager().shutdown();
            DialogDismiss();
            setTvEmpty();
        }
    }

    private void setTvEmpty() {
        runOnUiThread(() -> tv.setText(""));
    }

    public void readJson(String json) throws JSONException {
        try {
            JSONObject jsonObject = new JSONObject(json);
            if (jsonObject.getInt("code") == 0) {
                Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd hh:mm:ss").create();
                JsonRootBean jsonRootBean = gson.fromJson(json, JsonRootBean.class);
                com.example.canteen.javaBean.Data data = jsonRootBean.getData();
                long balance = data.getBalance();
                int amount = data.getAmount();
                String s = String.valueOf(balance);
                String s1 = s.substring(0, s.length() - 2);
                String s2 = s.substring(s.length() - 2);
                showSuccessDialog(s1 + "." + s2);
                checkFeeAndPlayer(String.valueOf(amount));
            } else {
                showFailDialog(jsonObject.getString("message"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject jsonObject = new JSONObject(json);
            try {
                String msg = jsonObject.getString("msg");
                showFailDialog(msg);
            } catch (JSONException e1) {
                showFailDialog("服务器异常，请稍等或联系管理员");
            }
        }
    }

    private void responseReader(String json) throws JSONException {
        DialogDismiss();
        setTvEmpty();
        try {
            JSONObject jsonObject = new JSONObject(json);
            String flag = jsonObject.getString("flag");
            if (flag.equals("0")) {
                String actualmoney = jsonObject.getString("actualmoney");
                String balance = jsonObject.getString("balance");
                Log.d("余额", balance);
                checkFeeAndPlayer(actualmoney);
                showSuccessDialog(balance);
            } else {
                showFailDialog(jsonObject.getString("error"));
            }

        } catch (Exception e) {
            JSONObject jsonObject = new JSONObject(json);
            try {
                String msg = jsonObject.getString("msg");
                showFailDialog(msg);
            } catch (JSONException e1) {
                showFailDialog("服务器异常，请稍等或联系管理员");
            }
        }
    }

    public static String md5(String string) {
        if (org.apache.http.util.TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result.append(temp);
            }
            return result.toString().toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    protected void onDestroy() {
        WxPayFace.getInstance().releaseWxpayface(this);
        soundpool.release();
        super.onDestroy();
    }
}